package cn.edu.zufe.mjt.spinrg;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
 * @author 蒙锦涛
 * @date 2025/4/24
 * @description BeanDefinition 用于描述 Bean 的定义
 * BeanDefinition 类用于描述 Bean 的定义
 * 它包含了 Bean 的名称和如何创建 Bean 实例所需的信息
 * 主要功能包括初始化 Bean 实例以及提供访问 Bean 名称和构造器的方法
 */
public class BeanDefinition {

    // Bean 的名称
    private final String name;
    // 用于创建 Bean 实例的构造器
    private final Constructor<?> constructor;
    // 用于执行 Bean 的初始化方法
    private final Method postConstructMethod;

    private final List<Field> autowiredFields;
    private final Class<?> beanType;

    /**
     * 构造一个新的 BeanDefinition 实例
     * 通过给定的类型自动检测 Component 注解以确定 Bean 的名称，并初始化构造器
     *
     * @param type Bean 的类型
     * @throws RuntimeException 如果 Bean 类型没有默认构造器
     */
    public BeanDefinition(Class<?> type) {
        this.beanType = type;
        // 获取 Bean 的名称，如果没有指定，则使用类的简单名称
        Component component = type.getDeclaredAnnotation(Component.class);
        this.name = component.name().isEmpty() ? type.getSimpleName() : component.name();
        try {
            // 获取并初始化 Bean 类型的默认构造器
            this.constructor = type.getConstructor();
            // 获取并初始化 Bean 类型的初始化方法 （ 目前先只支持一个 PostConstruct 方法 ）
            this.postConstructMethod = Arrays.stream(type.getDeclaredMethods())
                    .filter(m -> m.isAnnotationPresent(PostConstruct.class))
                    .findFirst().orElse(null);

            this.autowiredFields = Arrays.stream(type.getDeclaredFields())
                    .filter(f -> f.isAnnotationPresent(Autowired.class))
                    .toList();
        } catch (NoSuchMethodException e) {
            // 如果没有找到默认构造器，抛出运行时异常
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取 Bean 的名称
     *
     * @return Bean 的名称
     */
    public String getName() {
        return name;
    }

    /**
     * 获取用于创建 Bean 实例的构造器
     *
     * @return Bean 的构造器
     */
    public Constructor<?> getConstructor() {
        return constructor;
    }

    /**
     * 设置用于执行 Bean 的初始化方法
     *
     * @return Bean 的初始化方法
     */
    public Method getPostConstructMethod() {
        return postConstructMethod;
    }

    /**
     *  获取 Bean 类型中所有带有 Autowired 注解的字段
     * @return List<Field> Bean 类型中所有带有 Autowired 注解的字段
     */
    public List<Field> getAutowiredFields() {
        return autowiredFields;
    }

    /**
     * 获取 Bean 的类型
     *
     * @return Bean 的类型
     */
    public Class<?> getBeanType() {
        return beanType;
    }
}
